using RugbyClubWpf.Models;
using RugbyClubWpf.Data;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Input;
using RugbyClubWpf.Helpers;
using RugbyClubWpf.Views;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;

namespace RugbyClubWpf.ViewModels
{
    /// <summary>
    /// ViewModel for the President view.
    /// </summary>
    public class PresidentViewModel : INotifyPropertyChanged
    {
        /// <summary>
        /// Gets or sets the collection of presidents.
        /// </summary>
        public ObservableCollection<President> Presidents { get; set; }
        /// <summary>
        /// Gets or sets the collection of coaches.
        /// </summary>
        public ObservableCollection<Coach> Coaches { get; set; }
        /// <summary>
        /// Gets or sets the collection of players.
        /// </summary>
        public ObservableCollection<Player> Players { get; set; }
        /// <summary>
        /// Gets or sets the collection of matches.
        /// </summary>
        public ObservableCollection<Match> Matches { get; set; }
        /// <summary>
        /// Gets or sets the collection of announcements.
        /// </summary>
        public ObservableCollection<Announcement> Announcements { get; set; }

        /// <summary>
        /// Gets the command to add a coach.
        /// </summary>
        public ICommand AddCoachCommand { get; }
        /// <summary>
        /// Gets the command to delete a coach.
        /// </summary>
        public ICommand DeleteCoachCommand { get; }
        /// <summary>
        /// Gets the command to update a coach.
        /// </summary>
        public ICommand UpdateCoachCommand { get; }
        /// <summary>
        /// Gets the command to add a player.
        /// </summary>
        public ICommand AddPlayerCommand { get; }
        /// <summary>
        /// Gets the command to delete a player.
        /// </summary>
        public ICommand DeletePlayerCommand { get; }
        /// <summary>
        /// Gets the command to update a player.
        /// </summary>
        public ICommand UpdatePlayerCommand { get; }
        /// <summary>
        /// Gets the command to add an announcement.
        /// </summary>
        public ICommand AddAnnouncementCommand { get; }
        /// <summary>
        /// Gets the command to delete an announcement.
        /// </summary>
        public ICommand DeleteAnnouncementCommand { get; }
        /// <summary>
        /// Gets the command to update an announcement.
        /// </summary>
        public ICommand UpdateAnnouncementCommand { get; }

        private Coach _selectedCoach;
        /// <summary>
        /// Gets or sets the selected coach.
        /// </summary>
        public Coach SelectedCoach
        {
            get => _selectedCoach;
            set
            {
                _selectedCoach = value;
                OnPropertyChanged();
            }
        }

        private Player _selectedPlayer;
        /// <summary>
        /// Gets or sets the selected player.
        /// </summary>
        public Player SelectedPlayer
        {
            get => _selectedPlayer;
            set
            {
                _selectedPlayer = value;
                OnPropertyChanged();
            }
        }

        private Announcement _selectedAnnouncement;
        /// <summary>
        /// Gets or sets the selected announcement.
        /// </summary>
        public Announcement SelectedAnnouncement
        {
            get => _selectedAnnouncement;
            set
            {
                _selectedAnnouncement = value;
                OnPropertyChanged();
            }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="PresidentViewModel"/> class.
        /// </summary>
        public PresidentViewModel()
        {
            using (var context = new RugbyClubContext())
            {
                Coaches = new ObservableCollection<Coach>(context.Coaches.ToList());
                Players = new ObservableCollection<Player>(context.Players.ToList());
                Matches = new ObservableCollection<Match>(context.Matches.ToList());
                Announcements = new ObservableCollection<Announcement>(context.Announcements.ToList());
            }

            AddCoachCommand = new RelayCommand(_ => AddCoach());
            DeleteCoachCommand = new RelayCommand(_ => DeleteCoach());
            UpdateCoachCommand = new RelayCommand(_ => UpdateCoach());
            AddPlayerCommand = new RelayCommand(_ => AddPlayer());
            DeletePlayerCommand = new RelayCommand(_ => DeletePlayer());
            UpdatePlayerCommand = new RelayCommand(_ => UpdatePlayer());
            AddAnnouncementCommand = new RelayCommand(_ => AddAnnouncement());
            DeleteAnnouncementCommand = new RelayCommand(_ => DeleteAnnouncement());
            UpdateAnnouncementCommand = new RelayCommand(_ => UpdateAnnouncement());
        }

        /// <summary>
        /// Adds a new coach.
        /// </summary>
        private void AddCoach()
        {
            var dialog = new AddCoachDialog
            {
                DataContext = new Coach()
            };
            if (dialog.ShowDialog() == true)
            {
                var newCoach = (Coach)dialog.DataContext;
                Coaches.Add(newCoach);
                using (var context = new RugbyClubContext())
                {
                    context.Coaches.Add(newCoach);
                    context.SaveChanges();
                }
            }
        }

        /// <summary>
        /// Deletes the selected coach.
        /// </summary>
        private void DeleteCoach()
        {
            if (SelectedCoach == null)
            {
                MessageBox.Show("Please select a coach to delete.");
                return;
            }

            using (var context = new RugbyClubContext())
            {
                context.Coaches.Remove(SelectedCoach);
                context.SaveChanges();
            }
            Coaches.Remove(SelectedCoach);
        }

        /// <summary>
        /// Updates the selected coach.
        /// </summary>
        private void UpdateCoach()
        {
            if (SelectedCoach == null)
            {
                MessageBox.Show("Please select a coach to update.");
                return;
            }

            var dialog = new UpdateCoachDialog
            {
                DataContext = SelectedCoach
            };
            if (dialog.ShowDialog() == true)
            {
                using (var context = new RugbyClubContext())
                {
                    context.Coaches.Update(SelectedCoach);
                    context.SaveChanges();
                }
            }
        }

        /// <summary>
        /// Adds a new player.
        /// </summary>
        private void AddPlayer()
        {
            var dialog = new AddPlayerDialog
            {
                DataContext = new Player()
            };
            if (dialog.ShowDialog() == true)
            {
                var newPlayer = (Player)dialog.DataContext;
                Players.Add(newPlayer);
                using (var context = new RugbyClubContext())
                {
                    context.Players.Add(newPlayer);
                    context.SaveChanges();
                }
            }
        }

        /// <summary>
        /// Deletes the selected player.
        /// </summary>
        private void DeletePlayer()
        {
            if (SelectedPlayer == null)
            {
                MessageBox.Show("Please select a player to delete.");
                return;
            }

            using (var context = new RugbyClubContext())
            {
                context.Players.Remove(SelectedPlayer);
                context.SaveChanges();
            }
            Players.Remove(SelectedPlayer);
        }

        /// <summary>
        /// Updates the selected player.
        /// </summary>
        private void UpdatePlayer()
        {
            if (SelectedPlayer == null)
            {
                MessageBox.Show("Please select a player to update.");
                return;
            }

            var dialog = new UpdatePlayerDialog
            {
                DataContext = SelectedPlayer
            };
            if (dialog.ShowDialog() == true)
            {
                using (var context = new RugbyClubContext())
                {
                    context.Players.Update(SelectedPlayer);
                    context.SaveChanges();
                }
            }
        }

        /// <summary>
        /// Adds a new announcement.
        /// </summary>
        private void AddAnnouncement()
        {
            var dialog = new AddAnnouncementDialog
            {
                DataContext = new Announcement()
            };
            if (dialog.ShowDialog() == true)
            {
                var newAnnouncement = (Announcement)dialog.DataContext;
                Announcements.Add(newAnnouncement);
                using (var context = new RugbyClubContext())
                {
                    context.Announcements.Add(newAnnouncement);
                    context.SaveChanges();
                }
            }
        }

        /// <summary>
        /// Deletes the selected announcement.
        /// </summary>
        private void DeleteAnnouncement()
        {
            if (SelectedAnnouncement == null)
            {
                MessageBox.Show("Please select an announcement to delete.");
                return;
            }

            using (var context = new RugbyClubContext())
            {
                context.Announcements.Remove(SelectedAnnouncement);
                context.SaveChanges();
            }
            Announcements.Remove(SelectedAnnouncement);
        }

        /// <summary>
        /// Updates the selected announcement.
        /// </summary>
        private void UpdateAnnouncement()
        {
            if (SelectedAnnouncement == null)
            {
                MessageBox.Show("Please select an announcement to update.");
                return;
            }

            var dialog = new UpdateAnnouncementDialog
            {
                DataContext = SelectedAnnouncement
            };
            if (dialog.ShowDialog() == true)
            {
                using (var context = new RugbyClubContext())
                {
                    context.Announcements.Update(SelectedAnnouncement);
                    context.SaveChanges();
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged([CallerMemberName] string name = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }
    }
}
